<?php
namespace api\modules\v1\models;

use common\helpers\ArrayHelper;
use common\models\goods\Attr;
use common\models\goods\AttrValue;
use common\models\goods\Goods;
use common\models\goods\GoodsAttr;
use common\models\goods\GoodsCommon;
use common\models\goods\GoodsImage;
use yii\base\Model;
use common\models\member\MemberInfo;
use Yii;
use common\helpers\ResultDataHelper;
use yii\web\NotFoundHttpException;

/**
 * Class GoodsCreateForm
 * @package frontend\models
 */
class GoodsCreateForm extends Model
{
    public $goods_commonid;
    public $member_id;
    public $store_id;
    public $goods_name;
    public $goods_code;
    public $goods_bar;
    public $gc_id;
    public $goods_unit;
    public $brand_id;
    public $image_list;
    public $attr;
    public $goods_list;
    public $goods_price;
    public $goods_marketprice;
    public $goods_serial;
    public $goods_storage;
    public $goods_image;

    private $_attr_list = [];//属性-key列表
    private $_attr_value_list = [];//属性值-key列表

    private $_goods_total;//所有商品

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['goods_name', 'goods_code','goods_bar','goods_unit'], 'trim'],
            [['goods_name', 'member_id', 'store_id','goods_unit','gc_id','goods_storage'], 'required'],
            [['goods_name','goods_code','goods_bar','goods_serial'], 'string', 'max' => 50],
            ['goods_unit', 'string', 'max' => 10],
            [['member_id', 'store_id', 'gc_id', 'brand_id'], 'integer'],
            [['image_list','attr','goods_list'],'string'],
            [['goods_price','goods_marketprice'],'number']
        ];
    }

    public function attributeLabels()
    {
        return [
            'member_id' => '用户ID',
            'store_id' => '店铺ID',
            'goods_name' => '商品名称',
            'goods_code' => '商品编码',
            'goods_bar' => '商品条形码',
            'gc_id' => '分类ID',
            'goods_unit' => '单位',
            'image_list' => '图片json',
            'attr' => '规格列表',
            'goods_list'=>'商品列表',
            'goods_price'=>'价格',
            'goods_marketprice'=>'市场价',
            'goods_serial'=>'编号',
            'goods_storage'=>'库存'
        ];
    }

    /**
     * 添加商品
     */
    public function goodsCreate(){
        $goods_common = new GoodsCommon();
        $goods_common->member_id = $this->member_id;
        $goods_common->store_id = $this->store_id;
        $goods_common->goods_name = $this->goods_name;
        $goods_common->goods_code = $this->goods_code;
        $goods_common->goods_bar = $this->goods_bar;
        $goods_common->goods_unit = $this->goods_unit;
        $goods_common->gc_id = $this->gc_id;
        $goods_common->brand_id = $this->brand_id;
        $goods_common->goods_specname = $this->attr;

        $image_list = is_array($this->image_list)?$this->image_list:json_decode($this->image_list,false);
        $goods_image = $this->goods_image = $image_list[0]->goods_image??'';
        $goods_common->goods_image = $goods_image;
        $attr = is_array($this->attr)?$this->attr:json_decode($this->attr,false);
        $goods_list = is_array($this->goods_list)?$this->goods_list:json_decode($this->goods_list,false);

        if ($goods_common->validate())
        {
            $transaction = Yii::$app->db->beginTransaction();
            try {
                $goods_common->save();
                $goods_common_id = $this->goods_commonid = $goods_common->attributes['goods_commonid'];

                $this->saveImage($image_list);

                if (0 < count($attr)){
                    $this->saveAttr($attr);

                    $this->saveGoods($goods_list);
                }
                else{
                    $this->saveGoodsSingo();
                }
                $transaction->commit();
                return $goods_common_id;
            } catch (\Exception $e) {
                $transaction->rollBack();
                throw new NotFoundHttpException('添加商品事务失败：'.$e);
            }
        }
    }

    /**
     * 保存商品
     * @param $goods_list
     * @throws NotFoundHttpException
     */
    private function saveGoods($goods_list){
        //计算所有属性的组合
        if(count($this->_goods_total) != count($goods_list))
            throw new NotFoundHttpException('所有组合商品跟商品列表数量不符');

        //检测商品是否对应所有属性
        foreach ($goods_list as $_goods){
            $_attr = $_goods->attr;
            $_key = [];
            foreach ($_attr as $_k=>$_v){
                $_attr_value_id = $this->_attr_value_list[$_v->attr_name.'-'.$_v->attr_value_name];
                if(!$_attr_value_id)
                    throw new NotFoundHttpException('商品属性不能对应'.$_v->attr_name.'-'.$_v->attr_value_name);

                $_key[] = $_attr_value_id;
            }
            if(!$this->_goods_total[implode('-',$_key)])
                throw new NotFoundHttpException('商品属性不能对应'.implode('-',$_key));
            else{
                $this->_goods_total[implode('-',$_key)]['goods'] = $_goods;
            }
        }
        foreach ($this->_goods_total as $_g){
            if(!$_g['goods'])
                throw new NotFoundHttpException('组合商品不能完全对应，请检查商品json是否正确');
        }

        $GoodsModel = new Goods();
        $GoodsAttrModel = new GoodsAttr();

        foreach($goods_list as $goods_item){
            $goods_model = clone $GoodsModel;
            $goods_model->attributes = [
                'goods_commonid'=>$this->goods_commonid,
                'goods_name' => $this->goods_name,
                'goods_code' => $goods_item->goods_code??'',
                'goods_bar' => $goods_item->goods_bar??'',
                'gc_id' => $this->gc_id??0,
                'member_id' => $this->member_id,
                'store_id' => $this->store_id,
                'brand_id' => $this->brand_id??0,
                'goods_price' => $goods_item->goods_price??0,
                'goods_marketprice' => $goods_item->goods_marketprice??0,
                'goods_spec'=> json_encode($goods_item->attr),
                'goods_storage'=>$goods_item->goods_storage??0,
                'goods_image' => $this->goods_image,
            ];
            if($goods_model->validate() && $goods_model->save()){
                //插入商品-属性关联
                $goods_id = $goods_model->attributes['goods_id'];

                $goods_attr_list = is_array($goods_item->attr)?$goods_item->attr:json_decode($goods_item->attr,false);

                foreach($goods_attr_list as $goods_attr_item){
                    $attr_id = $this->_attr_list[$goods_attr_item->attr_name]??0;
                    $attr_value_id = $this->_attr_value_list[$goods_attr_item->attr_name."-".$goods_attr_item->attr_value_name]??0;
                    if($attr_id && $attr_value_id){
                        $goods_attr_model = clone $GoodsAttrModel;
                        $goods_attr_model->attributes = [
                            'goods_id'=>$goods_id,
                            'goods_commonid'=>$this->goods_commonid,
                            'attr_id'=>$attr_id,
                            'attr_value_id'=>$attr_value_id
                        ];
                        if($goods_attr_model->validate() && $goods_attr_model->save()){
                        }else
                            throw new NotFoundHttpException('添加商品-属性失败：'.json_encode($goods_attr_model->attributes));
                    }else
                        throw new NotFoundHttpException('添加商品-属性失败：属性对应出错'.$goods_attr_item->attr_name."-".$goods_attr_item->attr_value_name);
                }
            }
            else
                throw new NotFoundHttpException('添加商品失败：'.json_encode($goods_model->attributes));
        }
    }

    /**
     * 保存属性
     * @param $attr
     * @throws NotFoundHttpException
     */
    private function saveAttr($attr){
        //检测属性是否有重复
        foreach ($attr as $_attr){
            $_array = [];
            foreach ($_attr->values as $_v){
                $_array[] = $_v->attr_value_name;
            }
            if(count($_attr->values) != count(array_unique($_array)))
                throw new NotFoundHttpException('添加属性值失败：属性值不能相同');
        }

        $AttrModel = new Attr();
        $AttrValueModel = new AttrValue();

        $_attr_total = [];
        $_attr_key_total = [];

        //插入商品属性
        foreach ($attr as $key=>$spec_item){
            $attr_model = clone $AttrModel;
            $attr_model->attributes = [
                'member_id'=>$this->member_id,
                'store_id'=>$this->store_id,
                'goods_commonid'=>$this->goods_commonid,
                'attr_name'=>$spec_item->attr_name,
                'attr_value'=>json_encode($spec_item->values)??[],
                'attr_show'=>$spec_item->attr_show,
                'attr_sort'=>$spec_item->attr_sort,
            ];
            if($attr_model->validate() && $attr_model->save()){
                $attr_id = $attr_model->attributes['attr_id'];

                $this->_attr_list[$spec_item->attr_name] = $attr_id;
                $_values = [];

                //插入商品属性值
                foreach ($spec_item->values as $attr_value_item) {
                    $attr_value_model = clone $AttrValueModel;
                    $attr_value_model->attributes = [
                        'member_id' => $this->member_id,
                        'store_id' => $this->store_id,
                        'attr_value_name' => $attr_value_item->attr_value_name,
                        'attr_id' => $attr_id,
                        'attr_value_sort' => $attr_value_item->attr_value_sort
                    ];

                    if ($attr_value_model->validate() && $attr_value_model->save()) {
                        $attr_value_id = $attr_value_model->attributes['attr_value_id'];

                        $_values[] = $attr_value_id;
                        $_attr_key_total[$key][$attr_value_id] = [
                            'attr_id'=>$attr_id,
                            'attr_name'=>$spec_item->attr_name,
                            'attr_value_id'=>$attr_value_id,
                            'attr_value_name'=>$attr_value_item->attr_value_name
                        ];

                        $this->_attr_value_list[$spec_item->attr_name.'-'.$attr_value_item->attr_value_name] = $attr_value_id;
                    }else
                        throw new NotFoundHttpException('添加属性值失败：'.json_encode($attr_value_model->attributes));

                }

                $_attr_total[] = [
                    'attr_id' => $attr_id,
                    'values' => $_values
                ];
            }
            else
                throw new NotFoundHttpException('添加属性失败：'.json_encode($attr_model->attributes));
        }
        $this->_goods_total = $this->mathAllGoods($_attr_total, $_attr_key_total);
    }

    /**
     * 计算所有组合商品
     * @param $attr_total
     * @param $_attr_key_total
     * @return array
     */
    private function mathAllGoods($attr_total, $_attr_key_total){
        $row = [];
        foreach ($attr_total as $_attr){
            $row[] = $_attr['values'];
        }
        $list = ArrayHelper::combination($row);
        $goods_list = [];
        foreach ($list as $k=>$v){
            $_attr = [];
            foreach ($v as $kk=>$vv){
                $_attr[] = $_attr_key_total[$kk][$vv];
            }
            $goods_list[implode('-',$v)] = [
                'attr'=>$_attr,
                'goods'=>null
            ];
        }
        return $goods_list;
    }

    /**
     * 保存单个商品
     * @throws NotFoundHttpException
     */
    private function saveGoodsSingo(){
        $goods_model = new Goods();
        $goods_model->attributes = [
            'goods_commonid'=>$this->goods_commonid,
            'goods_name' => $this->goods_name,
            'goods_code' => $this->goods_code,
            'goods_bar' => $this->goods_bar,
            'gc_id' => $this->gc_id??0,
            'member_id' => $this->member_id,
            'store_id' => $this->store_id,
            'brand_id' => $this->brand_id??0,
            'goods_price' => $this->goods_price,
            'goods_marketprice' => $this->goods_marketprice??0,
            'goods_spec'=> json_encode([]),
            'goods_storage'=>$this->goods_storage,
            'goods_image' => $this->goods_image,
        ];
        if($goods_model->validate() && $goods_model->save()){

        }else
            throw new NotFoundHttpException('添加商品-图片失败：'.json_encode($goods_model->attributes));
    }

    /**
     * 保存图片
     * @param $image_list
     * @throws NotFoundHttpException
     */
    private function saveImage($image_list){
        $GoodsImageModel = new GoodsImage();

        //插入商品图片
        foreach ($image_list as $image_item){
            $goods_image_model = clone $GoodsImageModel;
            $goods_image_model->attributes = [
                'member_id' => $this->member_id,
                'store_id' => $this->store_id,
                'goods_commonid' => $this->goods_commonid,
                'goods_image' => $image_item->goods_image??'',
                'goods_image_sort' => $image_item->goods_image_sort??0,
                'is_default' => $image_item->is_default??0
            ];
            if($goods_image_model->validate() && $goods_image_model->save()){
                //保存成功
            }else
                throw new NotFoundHttpException('添加商品-图片失败：'.json_encode($goods_image_model->attributes));
        }
    }
}
